package com.haixiaoke.saas.repository.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.haixiaoke.saas.repository.dto.CalendarPriceDTO;
import com.haixiaoke.saas.repository.exception.BizException;
import com.haixiaoke.saas.repository.mapper.CalendarPriceMapper;
import com.haixiaoke.saas.repository.pojo.CalendarPrice;
import com.haixiaoke.saas.repository.pojo.HousingAllocation;
import com.haixiaoke.saas.repository.service.ICalendarPriceService;
import com.haixiaoke.saas.repository.service.IHousingAllocationService;
import com.haixiaoke.saas.repository.util.timePair.TimePair;
import com.haixiaoke.saas.repository.util.timePair.TimePairCompareUtil;
import com.mzj.saas.commons.StatusCode;
import jodd.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 日历价格Service业务层处理
 *
 * @author 嗨小克
 * @date 2023-05-23
 */
@Service
public class CalendarPriceServiceImpl implements ICalendarPriceService {
    @Autowired
    private CalendarPriceMapper calendarPriceMapper;
    @Autowired
    private IHousingAllocationService iHousingAllocationService;

    /**
     * 查询日历价格
     *
     * @param id 日历价格主键
     * @return 日历价格
     */
    @Override
    public CalendarPrice selectCalendarPriceById(Long id) {
        return calendarPriceMapper.selectCalendarPriceById(id);
    }

    /**
     * 查询日历价格列表
     *
     * @param calendarPrice 日历价格
     * @return 日历价格
     */
    @Override
    public List<CalendarPrice> selectCalendarPriceList(CalendarPrice calendarPrice) {
        return calendarPriceMapper.selectCalendarPriceList(calendarPrice);
    }

    /**
     * 新增日历价格
     *
     * @param calendarPrice 日历价格
     * @return 结果
     */
    @Override
    public int insertCalendarPrice(CalendarPrice calendarPrice) {
        return calendarPriceMapper.insertCalendarPrice(calendarPrice);
    }

    @Override
    @Transactional
    public int insertBatchCalendarPrice(CalendarPriceDTO calendarPriceDTO) {
        String houseId = calendarPriceDTO.getHouseId();
        if (StringUtil.isEmpty(houseId)) return 0;
        int count = calendarPriceMapper.deleteCalendarPriceByHouseId(houseId);
        //封装对象list
        if (CollectionUtil.isNotEmpty(calendarPriceDTO.getCalendarPriceList())) {
            List<TimePair> timePairs = calendarPriceDTO.getCalendarPriceList().stream().map(x ->
                    new TimePair(x.getStartTime().getTime(), x.getEndTime().getTime())
            ).collect(Collectors.toList());
            if (!TimePairCompareUtil.isOverlap(timePairs, false)) {
                HousingAllocation housingAllocation = iHousingAllocationService.selectHousingAllocationByHouseId(houseId);
                if (ObjectUtil.isNotEmpty(housingAllocation)) {
                    calendarPriceDTO.getCalendarPriceList().forEach(x -> {
                        x.setAllocationId(housingAllocation.getAllocationId());
                        x.setHouseId(houseId);
                    });
                }
                return calendarPriceMapper.insertBatchCalendarPrice(calendarPriceDTO.getCalendarPriceList());
            } else {
                throw new BizException(Integer.valueOf(StatusCode.ERROR_CODE_10005.getErrorCode()), "日期重复，请重新选择");
            }
        }
        return count;
    }

    /**
     * 修改日历价格
     *
     * @param calendarPrice 日历价格
     * @return 结果
     */
    @Override
    public int updateCalendarPrice(CalendarPrice calendarPrice) {
        return calendarPriceMapper.updateCalendarPrice(calendarPrice);
    }

    /**
     * 批量删除日历价格
     *
     * @param ids 需要删除的日历价格主键
     * @return 结果
     */
    @Override
    public int deleteCalendarPriceByIds(Long[] ids) {
        return calendarPriceMapper.deleteCalendarPriceByIds(ids);
    }

    /**
     * 删除日历价格信息
     *
     * @param id 日历价格主键
     * @return 结果
     */
    @Override
    public int deleteCalendarPriceById(Long id) {
        return calendarPriceMapper.deleteCalendarPriceById(id);
    }

    @Override
    public List<CalendarPrice> selectCalendarPriceByHouseId(String houseId) {
        return calendarPriceMapper.selectCalendarPriceByHouseId(houseId);
    }

    @Override
    public List<CalendarPriceDTO> calendarPriceSplit(List<CalendarPrice> calendarPriceList, Date checkInTime, Date checkOutTime) {
        List<CalendarPriceDTO> timeList = new ArrayList<>();
        //封装对象list
        List<TimePair> timePairs = calendarPriceList.stream().map(x ->
                new TimePair(x.getStartTime().getTime(), x.getEndTime().getTime())
        ).collect(Collectors.toList());

        long start = checkInTime.getTime();
        long end = checkOutTime.getTime();

        //将当前欲订单的时间段加入集合比较
        TimePair timePair = new TimePair(start, end);
        timePairs.add(timePair);

        if (TimePairCompareUtil.isOverlap(timePairs, false)) {
            timePairs.remove(timePairs.size() - 1);
            //日历时间包含租赁时间；租赁时间包含日历时间；头不在尾在；尾不在头在
            for (CalendarPrice calendarPrice : calendarPriceList) {
                long calendarStart = calendarPrice.getStartTime().getTime();
                long calendarEnd = calendarPrice.getEndTime().getTime();
                if (start - calendarStart >= 0 && calendarEnd - end >= 0) {
                    CalendarPriceDTO dto = new CalendarPriceDTO();
                    dto.setStartTime(checkInTime);
                    dto.setEndTime(checkOutTime);
                    dto.setPrice(calendarPrice.getPrice());
                    timeList.add(dto);
                } else if (start - calendarStart < 0 && end - calendarEnd > 0) {
                    CalendarPriceDTO dto = new CalendarPriceDTO();
                    dto.setStartTime(calendarPrice.getStartTime());
                    dto.setEndTime(calendarPrice.getEndTime());
                    dto.setPrice(calendarPrice.getPrice());
                    timeList.add(dto);
                    //start在日历开始时间之前，end在日历结束时间之前且在日历开始时间之后
                } else if (start - calendarStart < 0 && calendarEnd - end >= 0 && end - calendarStart > 0) {
                    CalendarPriceDTO dto = new CalendarPriceDTO();
                    dto.setStartTime(calendarPrice.getStartTime());
                    dto.setEndTime(checkOutTime);
                    dto.setPrice(calendarPrice.getPrice());
                    timeList.add(dto);
                } else if (start - calendarStart >= 0 && end - calendarEnd > 0 && calendarEnd - start > 0) {
                    CalendarPriceDTO dto = new CalendarPriceDTO();
                    dto.setStartTime(checkInTime);
                    dto.setEndTime(calendarPrice.getEndTime());
                    dto.setPrice(calendarPrice.getPrice());
                    timeList.add(dto);
                }
            }
            timeList.stream().sorted(Comparator.comparing(CalendarPriceDTO::getStartTime).reversed())
                    .collect(Collectors.toList());
            return timeList;
        } else {
            return null;
        }
    }
}
